/**
 * class 类
 * public公共 private私有 protected保护
 * readonly
 * get set 存取器
 * static 静态属性
 * abstract 抽象类
 */

class Animal {
    private name: string;

    get getName(): string {
        return this.name;
    }

    set setName(val: string) {
        this.name = val;
    }

    constructor(theName: string) {
        this.name = theName;
    }
}

class Dog extends Animal {
    readonly tail: string = "dog_tail";
    static roar: boolean = true;

    constructor(name: string) {
        super(name);
    }
}

let dogTai = new Dog("taid");
console.log(dogTai); //Dog { name:'taid' }

let animal = new Animal("Bear");
//console.log(animal.name); //error TS2341: Property 'name' is private and only accessible within class 'Animal'.
console.log(animal.getName); //Bear
animal.setName = "Cat";
console.log(animal.getName); //Cat


// 构造函数也可以被标记成 protected。 这意味着这个类不能在包含它的类外被实例化，但是能被继承。


// 使用 readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。
console.log(dogTai.tail);//dog_tail
//dogTai.tail = 'cat_tail' // error TS2540: Cannot assign to 'tail' because it is a read-only property.


//static 静态属性：属性存在于类本身上面而不是类的实例上。
//dogTai.roar //Property 'roar' does not exist on type 'Dog'.
console.log(Dog.roar); //true


//抽象类 abstract： 不同于接口，抽象类可以包含成员的实现细节。
abstract class Animal1 {
    abstract makeSound(): void;

    move(): void {
        console.log("roaming the earch...");
    }
}


// 抽象方法不包含具体实现并且必须在派生类中实现
class Cat extends Animal1 {
    constructor() {
        super();
    }

    // 实现抽象方法
    makeSound() {
        console.log("make sound");
    }
}
